/*
*********************************************************************************************************
*                                                uC/OS
*                                         The Real-Time Kernel
*
*                      (c) Copyright 1992, 1993, Jean J. Labrosse, Plantation, FL
*                                          All Rights Reserved
*
*
*                                       80x86/80x88 Specific code
*                                           LARGE MEMORY MODEL
*
* File : x32s.c
* By   : Jean J. Labrosse
*********************************************************************************************************
*/

#include "ucos.h"

/*
*********************************************************************************************************
*                                        INITIALIZE A TASK'S STACK
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                           CREATE A TASK
*********************************************************************************************************
*/

/*
 * void (OS_FAR *task)(void *pd)			task entry point
 * void *pdata												argument given to entry point
 * void *pstk													pointer to stackframe
 * UBYTE p														task priority
 */
UBYTE OSTaskCreate(void (OS_FAR *task)(void *pd), void *pdata, void *pstk, UBYTE p)
{
    UWORD OS_FAR *stk;
    UBYTE  err;


    OS_ENTER_CRITICAL();
    if (OSTCBPrioTbl[p] == (OS_TCB *)0) {   /* Make sure task doesn't already exist at this priority   */
        OSTCBPrioTbl[p] = (OS_TCB *)1;      /* Reserve the priority to prevent others from doing ...   */
                                            /* ... the same thing until task is created.               */
        OS_EXIT_CRITICAL();
        stk    = (UWORD OS_FAR *)pstk;      /* Load stack pointer                                      */
    
        err      = OSTCBInit(p, (void OS_FAR *)stk, (void *)task, pdata);     /* Get and initialize a TCB       */

        if (err == OS_NO_ERR) {
            if (OSRunning) {                /* Find highest priority task if multitasking has started  */
                OSSched();
            }
        } else {
            OSTCBPrioTbl[p] = (OS_TCB *)0;  /* Make this priority available to others                  */
        }
        return (err);
    } else {
        OS_EXIT_CRITICAL();
        return (OS_PRIO_EXIST);
    }
}
